package com.bdqn.controller;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bdqn.pojo.Right;
import com.bdqn.pojo.Role;
import com.bdqn.service.RightService;
import com.bdqn.service.RoleService;
import com.bdqn.service.UserService;
import com.bdqn.shiro.MyShiroRealm;
import jakarta.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 角色模块控制器
 *
 * @author LILIBO
 * @since 2024/10/29
 */
@Controller
@RequestMapping("/role")
public class RoleController {

    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    @Resource
    private RightService rightService;

    /**
     * 角色列表
     */
    @RequiresPermissions("L0602")
    @RequestMapping("/list")
    public String list(Model model, String roleName, Long pageIndex) {
        // 当前要查询的页码，如果是null则设置为默认查第1页
        pageIndex = pageIndex == null ? 1 : pageIndex;

        // 分页查询用户列表
        Page page = new Page(pageIndex, 5L);
        Page<Role> rolePager = roleService.findPage(roleName, page);

        // 设置数据到作用域
        model.addAttribute("roleName", roleName); // 数据回显
        model.addAttribute("rolePager", rolePager);

        // 跳转页面
        return "role/list";
    }

    /**
     * 去添加页
     */
    @RequiresPermissions("L060201")
    @GetMapping("/add")
    public String toAdd(Model model) {
        // 查找所有权限，用于指派权限
        List<Right> rights = rightService.findAll();

        // 设置数据到作用域
        model.addAttribute("rights", rights);

        // 跳转页面
        return "role/add";
    }

    /**
     * 检查用户名是否可用（{"result":"true"} 表示已存在，不可用）
     */
    @ResponseBody // REST风格，直接将数据写入响应流（对应Ajax请求）
    @GetMapping("/check")
    public String checkRoleName(String roleName, Long roleId) {
        JSONObject json = new JSONObject();
        if (roleName == null) {
            json.put("result", "error");
            return json.toJSONString();
        }
        // 判断角色名称是否可用（排除某个ID）
        Role role = roleService.getByRoleNameExceptRoleId(roleName, roleId);
        json.put("result", String.valueOf(role != null));
        return json.toJSONString();
    }

    /**
     * 跳转到修改页
     */
    @RequiresPermissions("L060204")
    @GetMapping("/edit")
    public String toEdit(Model model, Long roleId) {
        // 查找所有权限，用于指派权限
        List<Right> rights = rightService.findAll();

        // 根据ID获取角色信息
        Role role = roleService.getById(roleId);

        // 通过角色ID获取对应的权限集合
        Set<Right> roleRights = rightService.findRightByRoleId(roleId);
        role.setRights(roleRights); // 权限角色拥有的权限集合

        // 将数据设置到作用域
        model.addAttribute("rights", rights);
        model.addAttribute("role", role);

        // 跳转页面
        return "role/edit";
    }

    /**
     * 保存角色信息（权限映射关系先删除再添加）
     */
    @RequiresPermissions("L060202")
    @PostMapping("/save")
    public String save(Role role, String[] rightCodes) {
        System.out.println(role);
        // 使用Lambda表达式打印数组信息
        Arrays.stream(rightCodes).forEach(code -> System.out.print(code + ' '));
        System.out.println();
        // 保存角色及对应的权限（兼容添加和修改）
        roleService.saveRoleAndRight(role, rightCodes);

        // 清空权限缓存
        RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
        MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
        realm.clearAllCachedAuthorizationInfo();
        // 重定向到列表页面
        return "redirect:/role/list";
    }

    /**
     * 删除角色
     */
    @RequiresPermissions("L060203")
    @ResponseBody
    @PostMapping("/del/{roleId}")
    public Map<String, Object> del(@PathVariable("roleId") Long roleId) {
        Map<String, Object> map = new HashMap<>();
        // 判断该角色是否有用户关联
        long count = userService.countByRoleId(roleId);
        if (count > 0) { // 有用户关联到该角色，不能删除
            map.put("result", "inuse");
            return map;
        }
        // 删除角色
        boolean result = roleService.del(roleId);
        map.put("result", String.valueOf(result));
        return map;
    }

}
